home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C027B.ZIP / JAS / SYM.C < prev   
Text File  |  1990-03-30  |  4KB  |  197 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. #define SYMSZ 64
  17. #define NHASH 373
  18. #define SYMLOOP(x,y) for(x=0;x<SYMSZ&&full[x]>0;x++) for(y=0;y<full[x];y++)
  19.  
  20. /* ordering definitions */
  21. #define O_SUPPRESS    000
  22. #define O_STATIC    001
  23. #define O_GLOBAL    002
  24. #define O_UNDEF        004
  25.  
  26. long nsyms = 0;
  27. SYM *table[NHASH];
  28.  
  29. SYM *sym_tab[SYMSZ];
  30. short full[SYMSZ];
  31. int level = 0;
  32. extern int Lflag;
  33.  
  34. SYM *
  35. newsym( )
  36. {
  37.     register SYM *p;
  38.  
  39.     if ( full[level] >= SYMSZ ) {
  40.         if ( ++level >= SYMSZ )
  41.             error( 0, "symbol table full" );
  42.     }
  43.     if (! sym_tab[level] ) {
  44.         sym_tab[level] = ALLOC(SYMSZ,SYM);
  45.         full[level] = 0;
  46.     }
  47.     p = &sym_tab[level][full[level]++];
  48.     p->flags = 0;
  49.     return p;
  50. }
  51.  
  52. SYM *
  53. lookup(name)
  54.     register char *name;
  55. {
  56.     register int h;
  57.     register SYM *p;
  58.  
  59.     h = hash( name );
  60.     if ( p = table[h] ) {
  61.         for ( ; p != (SYM *) NULL; p = p->next) {
  62.             if (! strcmp( name, p->name ) ) {
  63.                 return p;
  64.             }
  65.         }
  66.         p = newsym();
  67.         p->name = STRCPY(name);
  68.         p->next = table[h];
  69.         table[h] = p;
  70.         return p;
  71.     }
  72.     p = table[h] = newsym();
  73.     p->name = STRCPY(name);
  74.     return p;
  75. }
  76.  
  77. symwalk(acc,fun)
  78.     register int acc;
  79.     register int (*fun)();
  80. {
  81.     register int lvl, i;
  82.     register SYM *p;
  83.  
  84.     SYMLOOP(lvl,i) {
  85.         p = &sym_tab[lvl][i];
  86.  
  87.         if (acc & p->access)
  88.             (*fun)(p);
  89.         }
  90. }
  91.  
  92. putsym(p)
  93.     register SYM *p;
  94. {
  95.     struct {
  96.         char name[8];
  97.         unsigned short flags;
  98.         long value;
  99.     } s;
  100.     register int i;
  101.     register char *cp;
  102.  
  103.     cp = p->name;
  104.     for ( i = 0; i < 8 && *cp; )
  105.         s.name[i++] = *cp++;
  106.         for (; i < 8; )
  107.            s.name[i++] = '\0';
  108.  
  109.     s.value = p->value;
  110.  
  111.     s.flags = p->flags;
  112.     if ( s.flags == DEFINED || s.flags == (DEFINED|GLOBAL) )
  113.         s.flags |= EXTERN;
  114.  
  115.     output( (char *) &s, sizeof s, 1 );
  116. }
  117.  
  118. dumpsym()
  119. {
  120.     /*
  121.      * don't generate static symbols
  122.      */
  123.     if ( Lflag > 0 )
  124.         symwalk( O_STATIC, putsym );
  125.     symwalk( O_GLOBAL, putsym );
  126.     symwalk( O_UNDEF, putsym );
  127. }
  128.  
  129. setindex( p )
  130.     SYM *p;
  131. {
  132.     p->index = nsyms++;
  133. }
  134.  
  135. symindex()
  136. {
  137.     register int lvl, i;
  138.     register SYM *p;
  139.  
  140.     SYMLOOP(lvl,i) {
  141.         p = &sym_tab[lvl][i];
  142.         p->access = 0;
  143.         if ( (p->flags & DEFINED) == 0 ) {
  144.             p->access = O_SUPPRESS;
  145.         } else if ( (p->flags & (SEGMT|EQUATED)) &&
  146.                         ! (p->flags & GLOBAL) ) {
  147.             /*
  148.              * if a static symbol starts with an L,
  149.              * then it is truely invisible
  150.              */
  151.             if ( p->flags & SEGMT &&
  152.                     Lflag <= 1 && *(p->name) == 'L' )
  153.                 p->access = O_SUPPRESS;
  154.             else
  155.                 p->access = O_STATIC;
  156.         } else if ( p->flags & (SEGMT|EQUATED) ) {
  157.             p->access = O_GLOBAL;
  158.         } else { /*  (p->flags & SEGMT) == UNK */
  159.             p->access = O_UNDEF;
  160.         }
  161.     }
  162.     nsyms = 0;
  163.     /*
  164.      * don't generate static symbols
  165.      */
  166.     if ( Lflag > 0 )
  167.         symwalk( O_STATIC, setindex );
  168.     symwalk( O_GLOBAL, setindex );
  169.     symwalk( O_UNDEF, setindex );
  170. }
  171.  
  172. int
  173. hash(name)
  174.     register char *name;
  175. {
  176.     register int val;
  177.  
  178.     for (val = 0; *name; name++)
  179.         val += (int) *name;
  180.     return val % NHASH;
  181. }
  182.  
  183. fixsymval( addr, incr, segmt )
  184.     register long addr, incr;
  185.     unsigned short segmt;
  186. {
  187.     register int lvl, i;
  188.     register SYM *p;
  189.  
  190.     SYMLOOP(lvl,i) {
  191.         p = &sym_tab[lvl][i];
  192.  
  193.         if ( ( p->flags & SEGMT ) == segmt && p->value >= addr )
  194.             p->value += incr;
  195.     }
  196. }
  197.